home *** CD-ROM | disk | FTP | other *** search
/ HPAVC / HPAVC CD-ROM.iso / pc / BKISSSRC.ZIP / LOADER / RUNNER.ASM < prev    next >
Encoding:
Assembly Source File  |  1994-02-16  |  39.5 KB  |  847 lines

  1. ideal
  2. jumps
  3. model huge
  4. stack 1024
  5.  
  6. MAJORVER = 1        ;\ file format version 1.3
  7. MINORVER = 3        ;/
  8. MAXFILES = 50       ;maximum number of files allowed in library
  9. BUFFERSIZE = 4096   ;size of transfer buffer in bytes (less than 64k)
  10. FILES = 30          ;maximum number of 'FILES' in CONFIG.SYS to track
  11.  
  12.  
  13. ;******************
  14. ;*** structures ***
  15. ;******************
  16. STRUC ParmBlock
  17.         EnvSgmt     DW  0
  18.         CmdTail     DD  0
  19.         FCB_1       DD  0
  20.         FCB_2       DD  0
  21.         ExecAddr    DD  0
  22.         PgmStack    DD  0
  23. ENDS ParmBlock
  24. STRUC FCB
  25.         Filename    DB  11 DUP (' ')
  26.         Reserved    DB  5 DUP (0)
  27. ENDS FCB
  28. STRUC LibFile
  29.         Fileattr    DB  0
  30.         Filetime    DW  0
  31.         Filedate    DW  0
  32.         Filesize    DD  0
  33.         Filename    DB  13 DUP (0)
  34.         Fileoffset  DD  0
  35. ENDS LibFile
  36. STRUC DTA
  37.         DriveLetter DB  0                   ;+00 byte
  38.         Wildcard    DB  11 DUP (' ')        ;+01 byte(11)
  39.         AttrSearch  DB  0                   ;+0C byte
  40.         Reserved1   DW  0                   ;+0D word
  41.         Reserved2   DW  0                   ;+0F word
  42.         Reserved3   DW  0                   ;+11 word
  43.         Reserved4   DW  0                   ;+13 word
  44.         AttrFound   DB  0                   ;+15 byte
  45.         TimeFound   DW  0                   ;+16 word
  46.         DateFound   DW  0                   ;+18 word
  47.         SizeFound   DD  0                   ;+1A dword
  48.         FileFound   DB  13 DUP (' ')        ;+1E byte(13)
  49. ENDS DTA
  50.  
  51.  
  52.  
  53. ;**************
  54. ;*** macros ***
  55. ;**************
  56. MACRO ErrorMessage ErrorName,ErrorText
  57.     LOCAL @@Message,@@Quit
  58.     PROC    ErrorName
  59.             mov ah,9
  60.             push cs
  61.             pop ds
  62.             mov dx,offset @@Message
  63.             int 21h
  64.             cmp [Handle],0FFFFh
  65.             jz @@Quit
  66.             mov ah,3Eh
  67.             mov bx,[Handle]
  68.             int 21h
  69. @@Quit:     mov ax,4CFFh
  70.             int 21h
  71. @@Message   DB  '***Error*** ',ErrorText,0Dh,0Ah,'$'
  72.     ENDP    ErrorName
  73. ENDM ErrorMessage
  74. MACRO MAKEUPPERCASE letter
  75.     LOCAL @@NotLower
  76.     cmp letter,'a'
  77.     jb @@NotLower
  78.     cmp letter,'z'
  79.     ja @@NotLower
  80.     sub letter,'a'-'A'
  81. @@NotLower:
  82. ENDM MAKEUPPERCASE
  83.  
  84.  
  85.  
  86. SEGMENT     Code
  87.             ASSUME CS:Code, DS:Code
  88. ;░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
  89. ;░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
  90. ;░░░░░░░░░░░░░░░░░░░░░░░░░ Initialization ░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
  91. ;░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
  92. ;░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
  93. PROC        Start
  94.             mov [cs:PSPsegment],es
  95.             push cs                         ;\
  96.             pop ds                          ; \
  97.             mov ah,9                        ;  > display our greeting
  98.             mov dx,offset Hello             ; /
  99.             int 21h                         ;/
  100.             mov ah,30h                      ;\
  101.             int 21h                         ; \ make sure we have DOS 2.x +
  102.             cmp al,3                        ; /
  103.             jb OldDOSversion                ;/
  104.  
  105.             push cs                         ;\
  106.             pop ds                          ; \ create filename
  107.             mov di,offset LibName           ; /
  108.             call CreateFilename             ;/
  109.  
  110.             mov ax,[cs:PSPsegment]          ;\
  111.             mov es,ax                       ; \
  112.             mov bx,zzzzzseg                 ;  \
  113.             sub bx,ax                       ;   \ reduce memory overhead
  114.             add bx,2                        ;   /
  115.             mov ah,4Ah                      ;  /
  116.             int 21h                         ; /
  117.             jc ErrorChangingMemory          ;/
  118.             mov ah,49h                      ;\
  119.             mov es,[cs:PSPsegment]          ; \
  120.             mov es,[word es:002Ch]          ;  > free our environment space
  121.             int 21h                         ; /
  122.             jc ErrorChangingMemory          ;/
  123.  
  124.             ;*** Reading of the JLIB file header ***
  125.             mov ax,3D00h                    ;\
  126.             push cs                         ; \
  127.             pop ds                          ;  \
  128.             mov dx,offset LibName           ;   > try to open the library file
  129.             int 21h                         ;  /
  130.             jc BadLibName                   ; /
  131.             mov [Handle],ax                 ;/
  132. ;-------- 1.3 changes start here
  133.             mov ax,-4                       ;\
  134.             cwd                             ; \
  135.             mov cx,dx                       ;  \
  136.             mov dx,ax                       ;   > seek to 4 bytes before end
  137.             mov ax,4202h                    ;  /
  138.             mov bx,[Handle]                 ; /
  139.             int 21h                         ;/
  140.             mov ah,3Fh                      ;\
  141.             mov bx,[Handle]                 ; \
  142.             mov cx,4                        ;  > read in the offset to start
  143.             mov dx,offset HeaderOffset      ; /
  144.             int 21h                         ;/
  145.             mov ax,4201h                    ;\
  146.             mov bx,[Handle]                 ; \
  147.             xor cx,cx                       ;  > find out length of total file
  148.             xor dx,dx                       ; /
  149.             int 21h                         ;/
  150.             sub ax,[word HeaderOffset+0]    ;\
  151.             sbb dx,[word HeaderOffset+2]    ; \ compute offset to start of JLIB
  152.             mov [word HeaderOffset+0],ax    ; /
  153.             mov [word HeaderOffset+2],dx    ;/
  154.             mov ax,4200h                    ;\
  155.             mov bx,[Handle]                 ; \
  156.             mov cx,[word HeaderOffset+2]    ;  > seek to start of JLIB
  157.             mov dx,[word HeaderOffset+0]    ; /
  158.             int 21h                         ;/
  159. ;-------- 1.3 changes end here
  160.             mov ah,3Fh                      ;\
  161.             mov bx,[Handle]                 ; \
  162.             mov cx,6                        ;  \ read in signature and
  163.             mov dx,offset Buffer            ;  / file version number
  164.             int 21h                         ; /
  165.             jc FileError                    ;/
  166.             cmp [word Buffer],'LJ'          ;\
  167.             jnz BadSignature                ; \
  168.             cmp [word Buffer+2],'bi'        ;  \ check the signarure and
  169.             jnz BadSignature                ;  / file version number
  170.             cmp [word Buffer+4],MINORVER*256+MAJORVER
  171.             jnz BadSignature                ;/
  172.             mov ah,3Fh                      ;\
  173.             mov bx,[Handle]                 ; \
  174.             mov cx,2                        ;  \ read in number of files
  175.             mov dx,offset NumFiles          ;  / contained in the library
  176.             int 21h                         ; /
  177.             jc FileError                    ;/
  178.             mov cx,[NumFiles]               ;\
  179.             cmp cx,MAXFILES                 ; > check the limit of files
  180.             ja TooManyFiles                 ;/
  181.             mov ah,3Fh                      ;\
  182.             mov bx,[Handle]                 ; \
  183.             mov cx,4                        ;  \ read in the offset to the
  184.             mov dx,offset Transfer          ;  / directory structures
  185.             int 21h                         ; /
  186.             jc FileError                    ;/
  187.             mov ax,4200h                    ;\
  188.             mov bx,[Handle]                 ; \
  189.             mov cx,[word Transfer+2]        ;  \ seek to the beginning of
  190.             mov dx,[word Transfer+0]        ;  / the file structures
  191. ;-------- 1.3 changes start here
  192.             add dx,[word HeaderOffset+0]
  193.             adc cx,[word HeaderOffset+2]
  194. ;-------- 1.3 changes end here
  195.             int 21h                         ; /
  196.             jc FileError                    ;/
  197.             mov cx,[NumFiles]               ;\
  198.             mov dx,offset FileStats         ; \
  199. @@Read:     push cx dx                      ;  \
  200.             mov ah,3Fh                      ;   |
  201.             mov bx,[Handle]                 ;   |
  202.             mov cx,size LibFile             ;   | read in the directory
  203.             int 21h                         ;   | information for each file
  204.             jc FileError                    ;   |
  205.             pop dx cx                       ;  /
  206.             add dx,size LibFile             ; /
  207.             loop @@Read                     ;/
  208.             mov ah,3Eh                      ;\
  209.             mov bx,[Handle]                 ; \ close the library file
  210.             mov [Handle],-1                 ; /
  211.             int 21h                         ;/
  212.  
  213.             ;*** Installation of handler and execution of child ***
  214.             mov ax,3521h                    ;\
  215.             int 21h                         ; \ save the old int 21 vector
  216.             mov [word cs:OldInt21+0],bx     ; /
  217.             mov [word cs:OldInt21+2],es     ;/
  218.             mov ax,2521h                    ;\
  219.             mov dx,seg NewInt21             ; \
  220.             mov ds,dx                       ;  > hook our routine onto int 21
  221.             mov dx,offset NewInt21          ; /
  222.             int 21h                         ;/
  223.             mov [word cs:StackPTR+0],sp     ;\ save the stack for later
  224.             mov [word cs:StackPTR+2],ss     ;/
  225.             mov ax,4B00h                    ;load and execute program
  226.             mov dx,seg ProgramName          ;\
  227.             mov ds,dx                       ; > DS:DX ==> ASCIIZ program name
  228.             mov dx,offset ProgramName       ;/
  229.             mov bx,seg MyParmBlock          ;\
  230.             mov es,bx                       ; > ES:BX ==> parameter block
  231.             mov bx,offset MyParmBlock       ;/
  232.             cld
  233.             mov [word cs:MyParmBlock+offset (ParmBlock).EnvSgmt],0
  234.             mov [word cs:MyParmBlock+0+offset (ParmBlock).CmdTail],offset CommandTail
  235.             mov [word cs:MyParmBlock+2+offset (ParmBlock).CmdTail],seg CommandTail
  236.             mov [word cs:MyParmBlock+0+offset (ParmBlock).FCB_1],offset MyFCB_1
  237.             mov [word cs:MyParmBlock+2+offset (ParmBlock).FCB_1],seg MyFCB_1
  238.             mov [word cs:MyParmBlock+0+offset (ParmBlock).FCB_2],offset MyFCB_2
  239.             mov [word cs:MyParmBlock+2+offset (ParmBlock).FCB_2],seg MyFCB_2
  240.             int 21h                         ;call DOS
  241.             lahf                            ;\ save whether errors occurred
  242.             mov [cs:@@ErrorFlag],ax         ;/
  243.             cli                             ;\
  244.             mov sp,[word cs:StackPTR+0]     ; \ restore the stack
  245.             mov ss,[word cs:StackPTR+2]     ; /
  246.             sti                             ;/
  247.             mov ax,2521h                    ;\
  248.             lds dx,[cs:OldInt21]            ; > restore the int 21h vector
  249.             int 21h                         ;/
  250.             mov ax,cs                       ;\
  251.             mov es,ax                       ; > restore the segments
  252.             mov ds,ax                       ;/
  253.             mov ax,[cs:@@ErrorFlag]         ;\
  254.             test ah,1                       ; > if CARRY was set, handle error
  255.             jnz @@ExecError                 ;/
  256.             mov ax,4C00h                    ;\ terminate program
  257.             int 21h                         ;/
  258. @@ExecError:aam                             ;\
  259.             add ax,'00'                     ; \ convert and store
  260.             xchg ah,al                      ; / error number
  261.             mov [@@ExecNum],ax              ;/
  262.             mov ah,9                        ;\
  263.             mov dx,offset @@ExecMsg         ; > display error message
  264.             int 21h                         ;/
  265.             mov ax,4CFFh                    ;\ terminate program
  266.             int 21h                         ;/
  267. @@ExecMsg   db 'Error number '
  268. @@ExecNum   dw ?
  269. @@ExecMsg2  db ' (decimal) during execution of child process.',0Dh,0Ah,'$'
  270. @@ErrorFlag dw 0    ;high byte is copy of flags, low is value of AL
  271. ENDP        Start
  272. ;░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
  273. ;           DS:DI ==> location to place resulting filename
  274. ;
  275. proc        CreateFilename
  276.             mov ax,6200h                ;\
  277.             int 21h                     ; \
  278.             mov es,bx                   ;  > ES:BX ==> environment segment
  279.             mov es,[word es:2Ch]        ; /
  280.             xor bx,bx                   ;/
  281. @@FindStart:cmp [word es:bx],0000h      ;\
  282.             jz @@GotStart               ; \
  283.             inc bx                      ;  > ES:BX ==> filename of program
  284.             jmp @@FindStart             ; /
  285. @@GotStart: add bx,4                    ;/
  286. @@CopyName: mov al,[byte es:bx]         ;\
  287.             inc bx                      ; \
  288.             mov [byte ds:di],al         ;  \ copy the full pathname
  289.             inc di                      ;  /
  290.             or al,al                    ; /
  291.             jnz @@CopyName              ;/
  292.             ret                         ;return
  293. endp        CreateFilename
  294. ;░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
  295. ;the following data is used only during initialization of program
  296. Hello       DB  'JLIBHOST.COM -- JLib File Host, v','0'+MAJORVER,'.','0'+MINORVER,0Dh,0Ah
  297.             DB  'by  _______  /',0Dh,0Ah
  298.             DB  '       /    /      ┌──┌┐  │─┬─┌──┌─┐┌─┐┌─┐o┌──┌──┌──',0Dh,0Ah
  299.             DB  '      /    /       ├─ │└─┐│ │ ├─ ├┬┘├─┘├┬┘│└─┐├─ └─┐',0Dh,0Ah
  300.             DB  '/____/    /_____   └──│  └┘ │ └──│ \│  │ \│──┘└────┘',0Dh,0Ah
  301.             DB  0Dh,0Ah,'$'
  302. ;NowRunning  DB  'Now running under a JLIB Host environment.',0Dh,0Ah,'$'
  303. ;WelcomeBack DB  'Welcome back to reality.',0Dh,0Ah,'$'
  304. PSPsegment  DW  0                   ;our PSP segment
  305. StackPTR    DD  0                   ;saved stack pointer
  306. MyParmBlock ParmBlock <>            ;\
  307. MyFCB_1     FCB <>                  ; \
  308. MyFCB_2     FCB <>                  ;  > used for executing child process
  309. ProgramName DB 'LOADER.EXE',0       ; /
  310. CommandTail DB 0,127 DUP (0Dh)      ;/
  311. ;░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
  312. ;the following are all of the error messages, each created using a macro
  313. ErrorMessage ErrorChangingMemory,'Error during memory management.'
  314. ErrorMessage OldDOSversion,'This requires DOS 2.0 or higher.'
  315. ErrorMessage NoCommandLine,<'Bad command line syntax.',0Dh,0Ah,9,'JLIBHOST «libname.JLB» «program.EXE» «parameters»'>
  316. ErrorMessage BadLibName,'Error opening specified library.'
  317. ErrorMessage BadSignature,'Bad library format.'
  318. ErrorMessage TooManyFiles,'Too many files in library.'
  319. ErrorMessage FileError,'Error during file I/O.'
  320. ;░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
  321. ;░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
  322. ;░░░░░░░░░░░░░░░░░░░░ Library functions ░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
  323. ;░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
  324. ;░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
  325. ;the following data is needed by the library functions to access files
  326. OldInt21    DD 0                        ;old interrupt vector
  327. LibName     DB 127 DUP (0)              ;full filename of library file
  328. Handle      DW 0FFFFh                   ;
  329. Handle2     DW 0FFFFh                   ;
  330. NumFiles    DW 0                        ;number of files in library
  331. FileStats   LibFile MAXFILES DUP (<>)   ;file info structures of each file
  332. Buffer      DB 13 DUP (0)               ;
  333. Wildcard    DB 13 DUP (0)               ;\   last defined wildcard
  334. MasterAttr  DW 0                        ; \  original search attribute
  335. HandleNext  DB 0                        ;  > if next FindNext should be caught
  336. LastMatch   DW 0                        ; /  number of last match
  337. MasterWild  DB 80 DUP (0)               ;/   original search wildcard
  338. HandleList  DW FILES DUP (0)            ;list of which handles are what
  339. Transfer    DB BUFFERSIZE DUP (0)       ;transfer buffer (for dumping files)
  340. HeaderOffset DD 0                       ;offset to start of JLIB file
  341. ;░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
  342. ;capitalize filename, make sure there's a period, only allow 8 characters
  343. ;for the base name and 3 characters for the extension, doesn't allow
  344. ;characters after an asterick
  345. ;
  346. ;           DS:DX ==> ASCIIZ filename
  347. ;returns:   prepared filename is in 'Buffer'
  348. ;           ZF set if no filename passed (null name)
  349. PROC        FixFileName
  350.             push si bx ax                   ;save what we'll modify
  351.             mov si,dx                       ;DS:SI ==> source name
  352.             cmp [byte ds:si],0              ;\ quit with ZF set, if there's
  353.             jz @@Quit                       ;/ nothing given to us
  354. @@FindEnd:  inc si                          ;\
  355.             cmp [byte ds:si],0              ; > seek to the end of the name
  356.             jnz @@FindEnd                   ;/
  357.             std                             ;\
  358. @@FindStart:lodsb                           ; \
  359.             cmp si,dx                       ;  \
  360.             jz @@GotStart                   ;   | seek back to
  361.             cmp al,'\'                      ;   | the start of
  362.             jz @@IncOne                     ;   | the base name
  363.             cmp al,':'                      ;  /
  364.             jnz @@FindStart                 ; /
  365. @@IncOne:   add si,2                        ;/
  366. @@GotStart: mov bx,offset Buffer            ;CS:BX ==> place for final name
  367.             cld                             ;go forward, now
  368.             mov ah,8                        ;only copy 8 bytes for the base
  369. @@Basename: mov al,[byte ds:si]             ;\
  370.             or al,al                        ; \ load a byte, handling it
  371.             jz @@AddDot                     ; / if it's a NULL
  372.             inc si                          ;/
  373.             cmp al,'.'                      ;if we've found a period, start
  374.             jz @@AddDot                     ;  working on the extension
  375.             MAKEUPPERCASE al                ;\
  376.             mov [byte cs:bx],al             ; > make uppercase and store
  377.             inc bx                          ;/
  378.             cmp al,'*'                      ;if we've found an asterick, then
  379.             jz @@Ignore                     ;  ignore all up to period or end
  380.             dec ah                          ;\ only copy 8 characters
  381.             jnz @@Basename                  ;/
  382. @@Ignore:   mov al,[byte ds:si]             ;\
  383.             or al,al                        ; \
  384.             jz @@AddDot                     ;  \ skip until a NULL or a
  385.             inc si                          ;  / period is encountered
  386.             cmp al,'.'                      ; /
  387.             jnz @@Ignore                    ;/
  388. @@AddDot:   mov [byte cs:bx],'.'            ;\ tack on a period
  389.             inc bx                          ;/
  390.             mov ah,3                        ;only copy 3 bytes for the ext
  391. @@Extension:lodsb                           ;\  load a byte and handle
  392.             or al,al                        ; > it if it's a NULL
  393.             jz @@Done                       ;/
  394.             MAKEUPPERCASE al                ;\
  395.             mov [byte cs:bx],al             ; > make uppercase and store it
  396.             inc bx                          ;/
  397.             cmp al,'*'                      ;\ if we copied a '*', then there
  398.             jz @@Done                       ;/ shouldn't be anything after it
  399.             dec ah                          ;\ only copy 3 characters
  400.             jnz @@Extension                 ;/
  401. @@Done:     mov [byte cs:bx],0              ;\ terminate it with a NULL
  402.             or al,1               ;clear ZF ;/
  403. @@Quit:     pop ax bx si                    ;restore everything
  404.             ret                             ;return
  405. ENDP        FixFileName
  406. ;░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
  407. ;locates a file structure that matches identically to a specified file
  408. ;
  409. ;           ASCIIZ filename to match is in 'Buffer'
  410. ;returns:   SI ==> appropiate structure
  411. ;           AX = file number (0 based)
  412. ;           carry set if not found
  413. PROC        MatchFile
  414.             push di bx cx dx
  415.             xor ax,ax
  416.             mov si,offset FileStats
  417.             mov cx,[cs:NumFiles]
  418.             mov di,offset Buffer
  419. @@NewFile:  xor bx,bx
  420. @@Compare:  mov dl,[byte cs:si+bx+offset (LibFile).Filename]
  421.             or dl,dl
  422.             jz @@GotIt
  423.             cmp dl,[byte cs:di+bx]
  424.             jnz @@Next
  425.             inc bx
  426.             jmp @@Compare
  427. @@Next:     add si,size LibFile
  428.             inc ax
  429.             loop @@NewFile
  430.             stc                     ;signal error
  431.             jmp @@Quit
  432. @@GotIt:    clc                     ;signal success
  433. @@Quit:     pop dx cx bx di
  434.             ret
  435. ENDP        MatchFile
  436. ;░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
  437. ;locates a file structure that matches a specified wildcard
  438. ;
  439. ;           ASCIIZ wildcard to match is in 'Wildcard'
  440. ;           AX = file number from last call (-1 for first time)
  441. ;returns:   if CF clear then
  442. ;               SI ==> appropiate structure
  443. ;               AX = file number (0 based)
  444. ;           else
  445. ;               no more matching files or invalid starting number
  446. ;           endif
  447. PROC        MatchWild
  448.             push di bx cx dx bp
  449.             mov bx,ax                   ;\
  450.             inc bx                      ; \ make sure the start value is okay
  451.             cmp bx,[cs:NumFiles]        ; /
  452.             jae @@NoMore                ;/
  453.             inc ax                      ;AX = first entry to check
  454.             push ax                     ;\
  455.             mov bx,size LibFile         ; \
  456.             mul bx                      ;  \ SI ==> first structure to check
  457.             mov si,offset FileStats     ;  /
  458.             add si,ax                   ; /
  459.             pop ax                      ;/
  460.             mov cx,[cs:NumFiles]        ;\
  461.             sub cx,ax                   ; > CX = number of files to check
  462.             inc cx                      ;/
  463.             mov di,offset Wildcard      ;DI ==> wildcard string
  464. @@NewFile:  xor bx,bx
  465.             mov bp,offset (LibFile).Filename
  466. @@Compare:  mov dl,[byte cs:di+bx]      ;DL = wildcard letter
  467.             mov dh,[byte cs:si+bp]      ;DH = filename letter
  468.             inc bx
  469.             inc bp
  470.             cmp dl,'.'                  ;\
  471.             jz @@GotDot                 ; \
  472.             cmp dh,'.'                  ;  \
  473.             jnz @@NoDot                 ;   > period ('.')
  474. @@GotDot:   cmp dl,dh                   ;  /
  475.             jnz @@NoMatch               ; /
  476.             jmp @@Compare               ;/
  477. @@NoDot:    or dl,dl                    ;\
  478.             jz @@GotNull                ; \
  479.             or dh,dh                    ;  \
  480.             jnz @@NoNull                ;   > null (0h)
  481. @@GotNull:  cmp dh,dl                   ;  /
  482.             jz @@Found                  ; /
  483.             jmp @@NoMatch               ;/
  484. @@NoNull:   cmp dl,'?'                  ;\ question mark ('?')
  485.             jz @@Compare                ;/
  486.             cmp dl,'*'                  ;\
  487.             jnz @@NotStar               ; \
  488. @@Ignore:   mov dl,[byte cs:si+bp]      ;  \
  489.             cmp dl,'.'                  ;   |
  490.             jz @@Compare                ;   | asterick ('*')
  491.             or dl,dl                    ;   |
  492.             jz @@Compare                ;  /
  493.             inc bp                      ; /
  494.             jmp @@Ignore                ;/
  495. @@NotStar:  cmp dl,dh                   ;\ if it matches up, then go
  496.             jz @@Compare                ;/ on to the next character
  497. @@NoMatch:  add si,size LibFile         ;point to the next structure
  498.             inc ax                      ;increment our counter
  499.             loop @@NewFile              ;loop until we've searched all
  500. @@NoMore:   pop bp dx cx bx di          ;\
  501.             stc                         ; > quit unsucessfully
  502.             ret                         ;/
  503. @@Found:    pop bp dx cx bx di          ;\
  504.             clc                         ; > quit sucessfully
  505.             ret                         ;/
  506. ENDP        MatchWild
  507. ;░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
  508. ;░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
  509. ;░░░░░░░░░░░░░░░░░░░░ Interrupt handlers ░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
  510. ;░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
  511. ;░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
  512. PROC        NewInt21 FAR
  513.             cmp ah,3Dh
  514.             jz OpenFile
  515.             cmp ah,3Eh
  516.             jz CloseFile
  517.             cmp ah,4Eh
  518.             jz FindFirst
  519.             cmp ah,4Fh
  520.             jz FindNext
  521.             cmp ah,4Bh
  522.             jz Execute
  523.  
  524.             jmp [dword cs:OldInt21]
  525. ENDP        NewInt21
  526. ;░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
  527. ;           AL = access mode (0 = read, 1 = write, 2 = read/write)
  528. ;           DS:DX ==> ASCIIZ filename
  529. ;returns:   AX = file handle
  530. ;
  531. ;(to temporarily dump a file to disk, set AX = 0, DS:DX ==> filename)
  532. ;(will return an internal pointer in AX to be passed to CloseFile later)
  533. ;(if -1 is returned, then the file is not contained in the library)
  534. ;(remember to pushf before far calling this routine to simulate an interrupt)
  535. PROC        OpenFile FAR
  536.             push ds es bx cx dx si di ax
  537.             call FixFileName
  538.             jz @@CallOld
  539.             call MatchFile
  540.             jc @@CallOld
  541.  
  542.             ;*** Open up the library and dump out the file requested ***
  543.             mov ax,3D00h                            ;\
  544.             push cs                                 ; \
  545.             pop ds                                  ;  \
  546.             mov dx,offset LibName                   ;   \ reopen the library
  547.             pushf                                   ;   /
  548.             call [dword cs:OldInt21]                ;  /
  549.             jc @@CallOld                            ; /
  550.             mov [Handle],ax                         ;/
  551.             mov ax,4200h                            ;\
  552.             mov bx,[Handle]                         ; \
  553.             mov cx,[word si+2+LibFile.Fileoffset]   ;  \ position the pointer
  554.             mov dx,[word si+0+LibFile.Fileoffset]   ;  /
  555. ;-------- 1.3 changes start here
  556.             add dx,[word HeaderOffset+0]
  557.             adc cx,[word HeaderOffset+2]
  558. ;-------- 1.3 changes start here
  559.             pushf                                   ; /
  560.             call [dword cs:OldInt21]                ;/
  561.             mov ah,3Ch                              ;\
  562.             xor cx,cx                               ; \
  563.             mov dx,si                               ;  \
  564.             add dx,offset (LibFile).Filename        ;   > create the file
  565.             pushf                                   ;  /
  566.             call [dword cs:OldInt21]                ; /
  567.             mov [Handle2],ax                        ;/
  568.             mov cx,[word si+0+LibFile.Filesize]     ;\ DX:CX ==> size to copy
  569.             mov dx,[word si+2+LibFile.Filesize]     ;/
  570. @@CopyLoop: or dx,dx                                ;\
  571.             jnz @@CopyBig                           ; \
  572.             cmp cx,BUFFERSIZE                       ;  \
  573.             jbe @@CopySmall                         ;   \
  574. @@CopyBig:  push cx dx                              ;    |
  575.             mov ah,3Fh                              ;    |
  576.             mov bx,[Handle]                         ;    |
  577.             mov cx,BUFFERSIZE                       ;    |
  578.             mov dx,offset Transfer                  ;    |
  579.             pushf                                   ;    |
  580.             call [dword cs:OldInt21]                ;    |
  581.             mov ah,40h                              ;    |
  582.             mov bx,[Handle2]                        ;    |
  583.             mov cx,BUFFERSIZE                       ;    |
  584.             mov dx,offset Transfer                  ;    | dump the data from
  585.             pushf                                   ;    | the library into a
  586.             call [dword cs:OldInt21]                ;    | separate file
  587.             pop dx cx                               ;    | (a decompression
  588.             sub cx,BUFFERSIZE                       ;    | scheme could be
  589.             sbb dx,0                                ;    | implemented here
  590.             jmp @@CopyLoop                          ;    | if file compression
  591. @@CopySmall:jcxz @@CopyDone                         ;    | were to be added)
  592.             push cx                                 ;    |
  593.             mov ah,3Fh                              ;    |
  594.             mov bx,[Handle]                         ;    |
  595.             mov dx,offset Transfer                  ;    |
  596.             pushf                                   ;    |
  597.             call [dword cs:OldInt21]                ;    |
  598.             mov ah,40h                              ;    |
  599.             mov bx,[Handle2]                        ;    |
  600.             pop cx                                  ;   /
  601.             mov dx,offset Transfer                  ;  /
  602.             pushf                                   ; /
  603.             call [dword cs:OldInt21]                ;/
  604. @@CopyDone: mov ah,3Eh                              ;\
  605.             mov bx,[Handle]                         ; \
  606.             mov [Handle],-1                         ;  > close the library
  607.             pushf                                   ; /
  608.             call [dword cs:OldInt21]                ;/
  609.             mov ah,3Eh                              ;\
  610.             mov bx,[Handle2]                        ; \
  611.             mov [Handle2],-1                        ;  > close the output
  612.             pushf                                   ; /
  613.             call [dword cs:OldInt21]                ;/
  614.  
  615.  
  616.             ;*** let DOS open the temporary file ***
  617.             pop ax
  618.             cmp ah,3Dh              ;check to see if it's an internal call
  619.             jnz @@Internal          ;   if yes -- then just return a pointer
  620.             mov dx,si
  621.             add dx,offset (LibFile).Filename
  622.             pushf
  623.             call [dword cs:OldInt21]
  624.             mov di,ax
  625.             shl di,1
  626.             add di,offset HandleList
  627.             mov [word di],si
  628.             pop di si dx cx bx es ds
  629.             ret 2
  630. @@Internal: mov ax,si
  631.             pop di si dx cx bx es ds
  632.             ret 2
  633. @@CallOld:  pop ax di si dx cx bx es ds
  634.             cmp ah,3Dh
  635.             jz @@CallOld2
  636.             mov ax,-1
  637.             ret 2
  638. @@CallOld2: jmp [dword cs:OldInt21]
  639. ENDP        OpenFile
  640. ;░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
  641. ;           BX = file handle
  642. ;
  643. ;(to delete an internally dumped, temporary file, set AX = 0, SI = pointer)
  644. ;(if a -1 is passed in SI, this function has no effect)
  645. ;(remember to pushf before far calling this routine to simulate an interrupt)
  646. PROC        CloseFile FAR
  647.             push ax bx cx dx si di ds es
  648.  
  649.             cmp ah,3Eh
  650.             jnz @@Internal
  651.  
  652.             ;*** if it's ours, set SI to its structure, else call DOS ***
  653.             mov di,bx
  654.             shl di,1
  655.             add di,offset HandleList
  656.             cmp [word cs:di],0
  657.             jz @@CallOld
  658.             mov si,[word cs:di]
  659.             mov [word cs:di],0
  660.  
  661.             ;*** close the file ***
  662.             mov ah,3Eh
  663.             pushf
  664.             call [dword cs:OldInt21]
  665.  
  666. @@Internal: ;*** and delete the temporary file ***
  667.             cmp si,-1
  668.             jz @@Quit
  669.             mov ah,41h
  670.             push cs
  671.             pop ds
  672.             mov dx,si
  673.             add dx,offset (LibFile).Filename
  674.             int 21h
  675.  
  676. @@Quit:     pop es ds di si dx cx bx ax
  677.             clc
  678.             ret 2
  679. @@CallOld:  pop es ds di si dx cx bx ax
  680.             jmp [dword cs:OldInt21]
  681. ENDP        CloseFile
  682. ;░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
  683. ;           CX = attributes to search for
  684. ;           DS:DX ==> ASCIIZ filespec
  685. ;returns:   AX = error code, if CF set
  686. ;           DTA contains search information
  687. PROC        FindFirst FAR
  688.             push ds es ax bx cx dx si di
  689.  
  690.             mov [cs:MasterAttr],cx          ;save original search attribute
  691.             mov si,dx                       ;\
  692.             mov di,offset MasterWild        ; \
  693.             push cs                         ;  \
  694.             pop es                          ;   \ save the original wildcard
  695.             mov cx,79                       ;   /
  696.             rep movsb                       ;  /
  697.             xor al,al                       ; /
  698.             stosb                           ;/
  699.             call FixFileName                ;\ process and parse the filespec
  700.             jz @@CallOld                    ;/
  701.             cld                             ;\
  702.             mov ax,cs                       ; \
  703.             mov ds,ax                       ;  |
  704.             mov es,ax                       ;  | transfer the wildcard
  705.             mov si,offset Buffer            ;  | into storage
  706.             mov di,offset Wildcard          ;  |
  707.             mov cx,12                       ; /
  708.             rep movsb                       ;/
  709.             mov ah,2Fh                      ;\
  710.             pushf                           ; > ES:BX ==> current DTA
  711.             call [dword cs:OldInt21]        ;/
  712.             mov di,bx                       ;\
  713.             mov cx,size DTA                 ; \ blank out the DTA
  714.             xor al,al                       ; /
  715.             rep stosb                       ;/
  716.             mov ax,-1                       ;\
  717.             call MatchWild                  ; \  do the search and save
  718.             jc @@CallOld                    ;  > what is needed to continue
  719.             mov [cs:LastMatch],ax           ; /  where we left off
  720.             mov [cs:HandleNext],1           ;/
  721.             mov di,bx                       ;\
  722.             add di,offset (DTA).AttrFound   ; \ copy over the stats about
  723.             mov cx,22                       ; / the file into the DTA
  724.             rep movsb                       ;/
  725.             pop di si dx cx bx ax es ds     ;\
  726.             clc                             ; > return with a successful find
  727.             ret 2                           ;/
  728. @@CallOld:  mov [cs:HandleNext],0           ;\
  729.             pop di si dx cx bx ax es ds     ; > start searching thru DOS
  730.             jmp [dword cs:OldInt21]         ;/
  731. ENDP        FindFirst
  732. ;░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
  733. PROC        FindNext FAR
  734.             push ds dx es ax bx cx si di
  735.  
  736.             cmp [cs:HandleNext],0           ;\ if we're not supposed to
  737.             jz @@CallOld                    ;/ handle this, then don't
  738.             mov ax,[cs:LastMatch]           ;\
  739.             call MatchWild                  ; \ continue searching, then save
  740.             jc @@StartOld                   ; / what's needed to continue
  741.             mov [cs:LastMatch],ax           ;/
  742.             push cs                         ;\ DS:SI ==> file structure
  743.             pop ds                          ;/
  744.             mov ah,2Fh                      ;\
  745.             pushf                           ; > ES:BX ==> current DTA
  746.             call [dword cs:OldInt21]        ;/
  747.             mov di,bx                       ;\
  748.             mov cx,size DTA                 ; \ blank out the DTA
  749.             xor al,al                       ; /
  750.             rep stosb                       ;/
  751.             mov di,bx                       ;\
  752.             add di,offset (DTA).AttrFound   ; \ copy over the stats about
  753.             mov cx,22                       ; / the file into the DTA
  754.             rep movsb                       ;/
  755.             pop di si cx bx ax es dx ds     ;\
  756.             clc                             ; > return with a successful find
  757.             ret 2                           ;/
  758. @@StartOld: mov [cs:HandleNext],0           ;\
  759.             pop di si cx bx ax es           ; \
  760.             mov ah,4Eh                      ;  \
  761.             mov cx,[cs:MasterAttr]          ;   \
  762.             push cs                         ;    \
  763.             pop ds                          ;     > start searching thru DOS
  764.             mov dx,offset MasterWild        ;    /
  765.             pushf                           ;   /
  766.             call [dword cs:OldInt21]        ;  /
  767.             pop dx ds                       ; /
  768.             ret 2                           ;/
  769. @@CallOld:  pop di si cx bx ax es dx ds     ;\ continue searching thru DOS
  770.             jmp [dword cs:OldInt21]         ;/
  771. ENDP        FindNext
  772. ;░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
  773. ;           DS:DX ==> ASCIIZ filename to run
  774. ;           ES:BX ==> Parameter block for exec function
  775. ;returns:   AX = error code, if CF set
  776. PROC        Execute FAR
  777.             mov [cs:@@Temp],si
  778.             mov si,[cs:ExecSavePtr]
  779.             cmp si,MaxExecNests*size ExecSaveType
  780.             jae @@Error
  781.             add [cs:ExecSavePtr],size ExecSaveType
  782.  
  783.             ;temporarily dump out the file
  784.             push ax
  785.             xor ax,ax
  786.             pushf
  787.             call OpenFile
  788.             mov [cs:offset ExecSave+si+offset (ExecSaveType).FilePointer],ax
  789.             pop ax
  790.  
  791.             ;let DOS execute it
  792.             mov [word cs:offset ExecSave+si+0+offset (ExecSaveType).StackPointer],sp
  793.             mov [word cs:offset ExecSave+si+2+offset (ExecSaveType).StackPointer],ss
  794.             mov si,[cs:@@Temp]
  795.             pushf                       ;\ simulate an int 21h to old handler
  796.             call [dword cs:OldInt21]    ;/
  797.  
  798.             ;get the system back to normality
  799.             cli
  800.             mov [cs:@@Temp],si
  801.             mov si,[cs:ExecSavePtr]
  802.             mov sp,[word cs:offset ExecSave+si-size ExecSaveType+0+offset (ExecSaveType).StackPointer]
  803.             mov ss,[word cs:offset ExecSave+si-size ExecSaveType+2+offset (ExecSaveType).StackPointer]
  804.             pushf
  805.             push ax
  806.             sti
  807.  
  808.             ;delete our temporary file
  809.             xor ax,ax
  810.             mov si,[cs:offset ExecSave+si-size ExecSaveType+offset (ExecSaveType).FilePointer]
  811.             pushf
  812.             call CloseFile
  813.  
  814.             ;deallocate this program's slot on our stack
  815.             sub [cs:ExecSavePtr],size ExecSaveType
  816.  
  817.             ;return (with current flag settings)
  818.             pop ax
  819.             popf
  820.             mov si,[cs:@@Temp]
  821.             ret 2
  822. @@Error:    stc
  823.             mov ax,5        ;return with 'access denied'
  824.             ret 2
  825. @@Temp      dw ?
  826. ENDP        Execute
  827. ;░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
  828. MaxExecNests = 10
  829. ExecSavePtr dw 0
  830. struc       ExecSaveType
  831.             StackPointer dd ?
  832.             FilePointer dw ?
  833. ends        ExecSaveType
  834. ExecSave    ExecSaveType MaxExecNests dup (<>)
  835. ;░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
  836. ;░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
  837. ;░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
  838. ;░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
  839. ;░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
  840. ENDS        Code
  841.  
  842. SEGMENT     zzzzzseg
  843.             DB 16 DUP(?)
  844. ENDS        zzzzzseg
  845.  
  846.             END     Start
  847.